import { memo, useRef, useState, useEffect } from 'react'
import { connect } from 'react-redux'
import {
  changeCurrentIndex,
  changeCurrentSong,
  changeFullScreen,
  changeMode,
  changePlayingState,
  changePlayList,
  changeShowPlayList
} from './store/actionCreator'
import MiniPlayer from './miniPlayer/index'
import NormalPlayer from './NormalPlayer/index'
import Toast from '../../baseUI/toast/index'
import { getSongUrl, isEmptyObj, findIndex, shuffle } from '../../api/utils'
import { playMode } from '../../api/config'

const mapStateToProps = state => ({
  fullScreen: state.getIn(['player', 'fullScreen']),
  playingState: state.getIn(['player', 'playingState']),
  sequencePlayList: state.getIn(['player', 'sequencePlayList']).toJS(),
  playList: state.getIn(['player', 'playList']).toJS(),
  mode: state.getIn(['player', 'mode']),
  currentIndex: state.getIn(['player', 'currentIndex']),
  showPlayList: state.getIn(['player', 'showPlayList']),
  currentSong: state.getIn(['player', 'currentSong']).toJS()
})

// 可以在这里将数据转成non-immutable吗？
const mapDispatchToProps = dispatch => ({
  togglePlayingStateDispatch(data) {
    dispatch(changePlayingState(data))
  },
  toggleFullScreenDispatch(data) {
    dispatch(changeFullScreen(data))
  },
  togglePlayListDispatch(data) {
    dispatch(changeShowPlayList(data))
  },
  toggleCurrentIndexDispatch(data) {
    dispatch(changeCurrentIndex(data))
  },
  toggleCurrentSongDispatch(data) {
    dispatch(changeCurrentSong(data))
  },
  toggleModeDispatch(data) {
    dispatch(changeMode(data))
  },
  changePlayListDispatch(data) {
    dispatch(changePlayList(data))
  }
})

function Player(props) {
  const {
    fullScreen,
    playingState,
    sequencePlayList,
    playList,
    mode,
    showPlayList,
    currentSong,
    currentIndex
  } = props
  const {
    toggleFullScreenDispatch,
    togglePlayingStateDispatch,
    togglePlayListDispatch,
    toggleCurrentIndexDispatch,
    toggleCurrentSongDispatch,
    toggleModeDispatch,
    changePlayListDispatch
  } = props

  const [duration, setDuration] = useState(0)
  const [currentTime, setCurrentTime] = useState(0)
  const [preSong, setPreSong] = useState({})
  const [modeText, setModeText] = useState('')
  // const [nextSong, setNextSong] = useState({})

  const audioRef = useRef()
  const toastRef = useRef()

  const percent = isNaN(currentTime / duration) ? 0 : currentTime / duration

  useEffect(() => {
    // if (!isEmptyObj(currentSong)) return
    if (
      !playList.length ||
      currentIndex === -1 ||
      !playList[currentIndex] ||
      playList[currentIndex].id === preSong.id
    ) {
      return
    }

    let current = playList[currentIndex]

    toggleCurrentSongDispatch(current)
    setPreSong(current)

    audioRef.current.src = getSongUrl(current.id)
    // setTimeout(() => {
    //   audioRef.current.autoplay = true
    // })

    // togglePlayingStateDispatch(true)
    setCurrentTime(0)
    setDuration(Math.ceil(current.dt / 1000)) // 取整运算
  })

  // 暂停和播放
  useEffect(() => {
    playingState ? audioRef.current.play() : audioRef.current.pause()
  }, [playingState])

  const clickPlaying = (e, state) => {
    e.stopPropagation()
    togglePlayingStateDispatch(state)
  }

  const updateTime = e => {
    setCurrentTime(e.target.currentTime)
  }

  const onProgressChange = curPercent => {
    const newTime = curPercent * duration

    setCurrentTime(newTime)
    audioRef.current.currentTime = newTime
    // if (!playingState) {
    //   togglePlayingStateDispatch(true)
    // }
  }

  const handleLoop = () => {
    audioRef.current.currentTime = 0
    togglePlayingStateDispatch(true)
    audioRef.current.play()
  }

  const handlePrev = () => {
    if (playList.length === 1) {
      handleLoop()
      return
    }

    let index = currentIndex - 1

    if (index < 0) index = playList.length - 1
    // if (!playing) togglePlayingStateDispatch(true)
    toggleCurrentIndexDispatch(index)
  }

  const handleNext = () => {
    if (playList.length === 1) {
      handleLoop()
      return
    }

    let index = currentIndex + 1

    if (index === playList.length) {
      index = 1
    }
    toggleCurrentIndexDispatch(index)
  }

  const handleEnd = () => {
    if (mode === playMode.loop) {
      handleLoop()
    } else {
      handleNext()
    }
  }

  const changeMode = () => {
    let newMode = (mode + 1) % 3

    if (newMode === 0) {
      changePlayListDispatch(sequencePlayList)
      let index = findIndex(currentSong, sequencePlayList)
      toggleCurrentIndexDispatch(index)
      setModeText('顺序循环')
    } else if (newMode === 1) {
      changePlayListDispatch(sequencePlayList)
      setModeText('单曲循环')
    } else if (newMode == 2) {
      let newList = shuffle(sequencePlayList)
      let index = findIndex(currentSong, newList)

      changePlayListDispatch(newList)
      toggleCurrentIndexDispatch(index)
      setModeText('随机循环')
    }

    toggleModeDispatch(newMode)
    toastRef.current.show()
  }

  return (
    <div>
      {isEmptyObj(currentSong) ? null : (
        <NormalPlayer
          playingState={playingState}
          song={currentSong}
          mode={mode}
          changeMode={changeMode}
          fullScreen={fullScreen}
          duration={duration}
          currentTime={currentTime}
          percent={percent}
          toggleFullScreen={toggleFullScreenDispatch}
          clickPlaying={clickPlaying}
          onProgressChange={onProgressChange}
          handlePrev={handlePrev}
          handleNext={handleNext}
        ></NormalPlayer>
      )}
      {isEmptyObj(currentSong) ? null : (
        <MiniPlayer
          playingState={playingState}
          song={currentSong}
          fullScreen={fullScreen}
          toggleFullScreen={toggleFullScreenDispatch}
          clickPlaying={clickPlaying}
        ></MiniPlayer>
      )}
      <audio ref={audioRef} onTimeUpdate={updateTime}></audio>
      <Toast ref={toastRef} text={modeText}></Toast>
    </div>
  )
}

export default connect(mapStateToProps, mapDispatchToProps)(memo(Player))
